package com.xbongbong.paas.service.stage.execute;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasProcessDataEntity;
import com.xbongbong.paas.domain.entity.PaasStageEntity;
import com.xbongbong.paas.domain.entity.PaasUserEntity;
import com.xbongbong.paas.domain.entity.StageLogEntity;
import com.xbongbong.paas.domain.entity.StageProcessEntity;
import com.xbongbong.paas.domain.entity.StageWorkLogEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasProcessTemplateEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.StageTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.help.ProFormHelp;
import com.xbongbong.paas.help.ProUpdateHelp;
import com.xbongbong.paas.help.StageLogHelp;
import com.xbongbong.paas.help.WorkflowTransferHelp;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.model.PaasProcessDataModel;
import com.xbongbong.paas.model.PaasProcessTemplateModel;
import com.xbongbong.paas.model.PaasStageModel;
import com.xbongbong.paas.model.PaasUserModel;
import com.xbongbong.paas.model.StageLogModel;
import com.xbongbong.paas.model.StageWorkLogModel;
import com.xbongbong.paas.pojo.dto.StartProcessDTO;
import com.xbongbong.paas.pojo.vo.StartProcessVO;
import com.xbongbong.paas.service.ProModelService;
import com.xbongbong.paas.service.stage.StageJumpHandle;
import com.xbongbong.paas.service.workflow.trigger.WorkflowFormDataOperationService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CloneUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.paas.util.FormDataUtil;
import com.xbongbong.paas.util.TitleUtil;
import com.xbongbong.pro.businessrule.pojo.BusinessRuleInfoPojo;
import com.xbongbong.pro.businesstage.pojo.dto.CommonJumpDTO;
import com.xbongbong.pro.businesstage.pojo.dto.StageFinishWorkDTO;
import com.xbongbong.pro.businesstage.pojo.dto.StageGetDTO;
import com.xbongbong.pro.businesstage.pojo.dto.StageJumpDealDTO;
import com.xbongbong.pro.businesstage.pojo.dto.StageJumpSpecialDealDTO;
import com.xbongbong.pro.businesstage.pojo.dto.StageJumpValidateDTO;
import com.xbongbong.pro.businesstage.pojo.vo.StageFinishWorkVO;
import com.xbongbong.pro.businesstage.pojo.vo.StageGetVO;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.constant.SymbolConstant;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.enums.PaasStageEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.workflow.TriggerEventTypeEnum;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.log.pojo.DetailLogPojo;
import com.xbongbong.pro.thread.ThreadPoolBeanConfig;
import com.xbongbong.pro.weblist.pojo.dto.SaasBaseDTO;
import com.xbongbong.pro.workflow.enums.WorkflowExecutionTypeEnum;
import com.xbongbong.pro.workflow.enums.WorkflowOperateEnum;
import com.xbongbong.process.operate.ProcessStartHelp;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.ContractProductEntity;
import com.xbongbong.saas.domain.entity.ContractUserEntity;
import com.xbongbong.saas.domain.entity.UserTeamEntity;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.model.ContractModel;
import com.xbongbong.saas.model.ContractProductModel;
import com.xbongbong.saas.model.ContractUserModel;
import com.xbongbong.saas.model.PaasFormDataModel;
import com.xbongbong.saas.service.UserTeamService;
import com.xbongbong.workflow.domain.entity.WorkflowBackupDataEntity;
import com.xbongbong.workflow.domain.entity.WorkflowEntity;
import com.xbongbong.workflow.domain.entity.WorkflowExecutionEntity;
import com.xbongbong.workflow.domain.entity.WorkflowNodeEntity;
import com.xbongbong.workflow.domain.entity.WorkflowTaskEntity;
import com.xbongbong.workflow.domain.entity.WorkflowTransferDataEntity;
import com.xbongbong.workflow.model.WorkflowBackupDataModel;
import com.xbongbong.workflow.model.WorkflowNodeModel;
import com.xbongbong.workflow.model.WorkflowTaskModel;
import com.xbongbong.workflow.model.WorkflowTransferDataModel;
import com.xbongbong.workflow.pojo.Data;
import com.xbongbong.workflow.pojo.WorkflowRabbitmqDTO;
import com.xbongbong.workflow.pojo.WorkflowTransferPOJO;
import com.xbongbong.workflow.pojo.nodes.FormTriggerNode;
import com.xbongbong.workflow.producer.WorkflowProducer;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.support.WriteRequest;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author 吴峰
 * @date 2021/11/22 19:26
 */
@Slf4j
@Service("paasStageExecuteHandleImpl")
public class PaasStageExecuteHandleImpl extends AbstractStageExecuteHandle {

    @Resource
    private PaasFormDataModel paasFormDataModel;
    @Resource
    private ContractModel contractModel;
    @Resource
    private StageLogModel stageLogModel;
    @Resource
    private PaasStageModel paasStageModel;
    @Resource
    private StageWorkLogModel stageWorkLogModel;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private ProModelService proModelService;
    @Resource
    private PaasProcessTemplateModel paasProcessTemplateModel;
    @Resource
    private WorkflowFormDataOperationService workflowFormDataOperationService;
    @Resource
    private WorkflowNodeModel workflowNodeModel;
    @Resource
    private WorkflowBackupDataModel workflowBackupDataModel;
    @Resource
    private WorkflowProducer workflowProducer;
    @Resource
    private ProcessStartHelp processStartHelp;
    @Resource
    private PaasProcessDataModel paasProcessDataModel;
    @Resource
    private WorkflowTransferDataModel workflowTransferDataModel;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private MongoLogHelp mongoLogHelp;
    @Resource
    private ThreadPoolBeanConfig threadPoolBeanConfig;
    @Resource
    private ProFormHelp proFormHelp;
    @Resource
    private Map<Integer, StageJumpHandle> stageJumpMap;
    @Resource
    private WorkflowTaskModel workflowTaskModel;
    @Resource
    private PaasUserModel paasUserModel;
    @Resource
    private ContractUserModel contractUserModel;
    @Resource
    private ContractProductModel contractProductModel;
    @Resource
    private StageLogHelp stageLogHelp;
    @Resource
    private UserTeamService userTeamService;
    @Resource
    private ProUpdateHelp proUpdateHelp;

    @Override
    public Integer type() {
        return XbbRefTypeEnum.PAAS.getCode();
    }

    @Override
    public void validate(StageJumpValidateDTO stageJumpValidateDTO) throws XbbException {

    }

    @Override
    public StageGetVO get(StageGetDTO stageGetDTO) throws XbbException {
        StageGetVO stageGetVO = new StageGetVO();
        stageGetVO.setStageShowType(0);
        String corpid = stageGetDTO.getCorpid();
        Long formId = stageGetDTO.getFormId();
        Long dataId = stageGetDTO.getDataId();
        Integer saasMark = stageGetDTO.getSaasMark();
        Integer businessType = stageGetDTO.getBusinessType();
        //老审批流转状态
        Integer approveFlowStatus = null;
        //工作流审批流转状态
        Integer workflowFlowStatus = null;

        PaasFormDataEntityExt paasFormDataEntityExt = new PaasFormDataEntityExt();
        if (Objects.equals(stageGetDTO.getApproveType(), BasicConstant.ONE)) {
            PaasProcessDataEntity processDataEntity = paasProcessDataModel.getByTaskId(stageGetDTO.getProcessTaskId(), corpid);
            paasFormDataEntityExt.setData(JSONObject.parseObject(processDataEntity.getData()));
            approveFlowStatus = processDataEntity.getFlowStatus();
        } else if (Objects.equals(stageGetDTO.getApproveType(), BasicConstant.TWO)) {
            WorkflowTransferDataEntity workflowTransferDataEntity = workflowTransferDataModel.getByTaskId(stageGetDTO.getProcessTaskId(), corpid);
            JSONObject workFlowData = workflowTransferDataEntity.getData();
            JSONObject dataJSONObject = workFlowData.getJSONObject("data");
            paasFormDataEntityExt.setData(dataJSONObject.getJSONObject("data"));
            WorkflowTaskEntity workflowTaskEntity = workflowTaskModel.getByKey(stageGetDTO.getProcessTaskId(), corpid);
            workflowFlowStatus = Objects.isNull(workflowTaskEntity) ? null : workflowTaskEntity.getFlowStatus();
        } else {
            // 合同阶段是个Paas字段
            // 这里可能是获取合同数据或者Paas数据
            paasFormDataEntityExt = (PaasFormDataEntityExt) proModelService.getFormDataEntity(corpid, saasMark, businessType, dataId);
            // 移动端透传关联数据时入参取不到最新formid
            formId = paasFormDataEntityExt.getFormId();
        }
        PaasFormExplainEntity explain = paasFormExplainModel.getByFormId(formId, corpid);
        if (Objects.isNull(explain)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }
        Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(explain.getExplains(), null);

        boolean checkshow = checkshow(stageGetDTO, paasFormDataEntityExt);
        if (!checkshow) {
            return stageGetVO;
        }
        Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Long stageProcessId = paasFormDataEntityExt.getData().getLong(PaasStageEnum.STAGE_PROCESS_ID.getAttr());
        StageProcessEntity stageProcessEntity = getStageProcessEntity(stageGetDTO, stageProcessId, null, explainMap, paasFormDataEntityExt);
        if (Objects.isNull(stageProcessEntity)) {
            return stageGetVO;
        }
        stageProcessId = stageProcessEntity.getId();

        List<StageLogEntity> stageLogEntities = new ArrayList<>();
        //审批会传dataId=0过来，规避这种情况
        if (Objects.nonNull(dataId) && !Objects.equals(dataId, BasicConstant.ZERO_LONG)) {
            params.put("corpid", corpid);
            params.put("del", 0);
            params.put("formId", formId);
            params.put("dataId", dataId);
            stageLogEntities = stageLogModel.findEntitys(params);
        }
        params.clear();
        params.put("corpid", corpid);
        params.put("formId", formId);
        params.put("stageProcessId", stageProcessId);
        params.put("del", 0);
        params.put("orderByStr", "sort desc,add_time asc");
        List<PaasStageEntity> paasStageEntityList = paasStageModel.findEntitys(params);
        Integer stageRation = paasFormDataEntityExt.getData().getInteger(PaasStageEnum.STAGE_RATIO.getAttr());
        // 主逻辑
        stageGetVO = stageGet(stageRation, paasFormDataEntityExt, stageProcessEntity, stageGetDTO, stageLogEntities, paasStageEntityList,approveFlowStatus, workflowFlowStatus);
        stageGetVO.setStageProcessId(stageProcessId);
        return stageGetVO;
    }

    @Override
    public StageFinishWorkVO finishWork(StageFinishWorkDTO stageFinishWorkDTO) throws XbbException {
        return stageFinishWork(stageFinishWorkDTO);
    }

    @Override
    public void stageWorkLogSave(StageWorkLogEntity stageWorkLogEntity) {
        stageWorkLogModel.save(stageWorkLogEntity);
    }

    @Override
    public List<StageWorkLogEntity> stageWorkLogFindEntitys(Map<String, Object> params) {
        List<StageWorkLogEntity> entitys = stageWorkLogModel.findEntitys(params);
        return Arrays.asList(entitys.toArray(new StageWorkLogEntity[0]));
    }

    @Override
    public boolean checkshow(StageGetDTO stageGetDTO, PaasFormDataEntityExt paasFormDataEntityExt) throws XbbException {
        String corpid = stageGetDTO.getCorpid();
        //审批阶段详情页不需要校验
        if (Objects.equals(stageGetDTO.getApproveType(), BasicConstant.ONE) || Objects.equals(stageGetDTO.getApproveType(), BasicConstant.TWO)) {
            return true;
        }
        if (Objects.isNull(paasFormDataEntityExt)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
        }
        Long formId = paasFormDataEntityExt.getFormId();
        PaasFormExplainEntity explain = paasFormExplainModel.getByFormId(formId, corpid);
        if (Objects.isNull(explain)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }
        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
        BeanUtil.copyProperties(stageGetDTO, handlerExplainDTO);
        if (Objects.equals(explain.getSaasMark(), SaasMarkEnum.SAAS.getCode())) {
            //协同团队
            Map<Long, List<String>> mainUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<Long, List<String>> coUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            userTeamService.getUserIdMap(Collections.singletonList(paasFormDataEntityExt.getId()), corpid, explain.getBusinessType(), false, mainUserMap, coUserMap);
            handlerExplainDTO.setOwnerId(mainUserMap.getOrDefault(paasFormDataEntityExt.getId(), new ArrayList<>()));
            handlerExplainDTO.setCoUserId(coUserMap.getOrDefault(paasFormDataEntityExt.getId(), new ArrayList<>()));
            handlerExplainDTO.setCreatorId(paasFormDataEntityExt.getCreatorId());
        } else {
            String ownerId = paasFormDataEntityExt.getOwnerId();
            List<String> ownerIds = new ArrayList<>();
            ownerIds.add(ownerId);
            handlerExplainDTO.setOwnerId(ownerIds);
        }
        FieldAttrEntity stageTruster = ExplainUtil.getPassStageAttr(explain);
        if (stageTruster != null) {
            Integer isOpen = stageTruster.getIsOpen();
            Boolean fieldNeedHide = ExplainUtil.isFieldNeedHide(stageTruster, handlerExplainDTO);
            if (isOpen != 1 || fieldNeedHide) {
                return false;
            }
        } else {
            return false;
        }
        return true;
    }

    @Override
    public boolean checkFieldEditable(SaasBaseDTO saasBaseDTO) throws XbbException {
        String corpid = saasBaseDTO.getCorpid();
        Integer businessType = saasBaseDTO.getBusinessType();
        Integer saasMark = saasBaseDTO.getSaasMark();
        Long dataId = saasBaseDTO.getDataId();
        PaasFormDataEntityExt paasFormDataEntityExt = (PaasFormDataEntityExt) proModelService.getFormDataEntity(corpid, saasMark, businessType, dataId);
        if (Objects.isNull(paasFormDataEntityExt)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
        }
        Long formId = paasFormDataEntityExt.getFormId();
        PaasFormExplainEntity explain = paasFormExplainModel.getByFormId(formId, corpid);
        if (Objects.isNull(explain)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
        }
        Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(explain.getExplains(), null);

        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
        BeanUtil.copyProperties(saasBaseDTO, handlerExplainDTO);
        if (Objects.equals(explain.getSaasMark(), SaasMarkEnum.SAAS.getCode())) {
            //协同团队
            Map<Long, List<String>> mainUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<Long, List<String>> coUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            userTeamService.getUserIdMap(Collections.singletonList(paasFormDataEntityExt.getId()), corpid, explain.getBusinessType(), false, mainUserMap, coUserMap);
            // 当前数据的创建人、负责人、协同人、当前操作人
            handlerExplainDTO.setOwnerId(mainUserMap.getOrDefault(paasFormDataEntityExt.getId(), new ArrayList<>()));
            handlerExplainDTO.setCoUserId(coUserMap.getOrDefault(paasFormDataEntityExt.getId(), new ArrayList<>()));
            handlerExplainDTO.setCreatorId(paasFormDataEntityExt.getCreatorId());
        } else {
            String ownerId = paasFormDataEntityExt.getOwnerId();
            List<String> ownerIds = new ArrayList<>();
            ownerIds.add(ownerId);
            handlerExplainDTO.setOwnerId(ownerIds);
        }
        FieldAttrEntity stageTruster = ExplainUtil.getPassStageAttr(explain);
        if (stageTruster == null) {
            return false;
        }
        return ExplainUtil.isStageEdit(stageTruster.getAttr(), explainMap, handlerExplainDTO);
    }

    @Override
    public void afterJumpDeal(StageJumpDealDTO stageJumpDealDTO, PaasFormDataEntityExt paasFormDataEntityExt) throws XbbException {
        if (!Objects.equals(stageJumpDealDTO.getIsImport(), 1)) {
            Runnable stageRemindTask = () -> addStageTimeOutRemind(stageJumpDealDTO, paasFormDataEntityExt);
            threadPoolBeanConfig.stageRemindThreadPool().execute(stageRemindTask);
        }

        Boolean isNew = stageJumpDealDTO.getIsNew();
        if (Objects.nonNull(isNew) && isNew) {
            return;
        }
        // fix: 2021/12/13 paas表单日志及消息推送待补充
        PaasStageEntity toStageEntity = stageJumpDealDTO.getToStageEntity();
        if (Objects.isNull(toStageEntity)) {
            toStageEntity = new PaasStageEntity();
            toStageEntity.setName("开始阶段");
            toStageEntity.setType(StageTypeEnum.START_STAGE.getType());
            toStageEntity.setBusinessRelatedStatus(-1);
        }
        PaasStageEntity fromStageEntity = stageJumpDealDTO.getFromStageEntity();
        String nowStageName = fromStageEntity == null ? "开始阶段" : fromStageEntity.getName();
        String stageName = toStageEntity.getName();
        String corpid = stageJumpDealDTO.getCorpid();
        Long formId = stageJumpDealDTO.getFormId();
        // 阶段推进器名称
        String stageAttrName = stageJumpDealDTO.getStageAttrName();
        Integer businessType = stageJumpDealDTO.getBusinessType();
        Runnable runnable = () -> {
            try {
                List<DetailLogPojo> detailArr = new ArrayList();
                // 生成项目日志
                String oldTitle = nowStageName;
                String newTitle = stageName;
                String newMsg = String.format(SymbolConstant.BRACKETS_SQUARE_SOLID, newTitle);
                String oldMsg = String.format(SymbolConstant.BRACKETS_SQUARE_SOLID, oldTitle);
                detailArr.add(new DetailLogPojo(stageAttrName, stageAttrName, oldMsg, newMsg));
                PaasFormEntityExt paasFormEntityExt = paasFormModel.getByKey(formId, corpid);
                PaasFormExplainEntity paasFormExplainEntity = proFormHelp.getExplainEntity(corpid, formId, businessType);
                Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(paasFormExplainEntity.getExplains(), null);
                String opObjectName = TitleUtil.getPaasFormTitle(paasFormDataEntityExt, paasFormEntityExt, explainMap);
                String memo = String.format(I18nMessageUtil.getMessage(I18nStringConstant.STAGE_OPERATION_LOG), stageJumpDealDTO.getLoginUserName(),
                        paasFormEntityExt.getName(), opObjectName);
                mongoLogHelp.buildLog4DetailArr(detailArr, corpid, stageJumpDealDTO.getUserId(), stageJumpDealDTO.getLoginUserName(),
                        OperateModuleTypeEnum.PAAS_FORM_DATA, OperateTypeEnum.EDIT, formId.toString(), opObjectName, memo, stageJumpDealDTO.getHttpHeader());
            } catch (Exception e) {
                log.error("阶段变更消息推送", e);
            }
        };
        threadPoolBeanConfig.addUpdateDelThreadPool().execute(runnable);
    }

    @Override
    public Integer approvalRequired(CommonJumpDTO commonJumpDTO, PaasFormDataEntityExt paasFormDataEntityExt, String stageAttr) throws XbbException {
        Integer noApprovalRequired = 1;
        String corpid = commonJumpDTO.getCorpid();
        Long formId = commonJumpDTO.getFormId();
        PaasStageEntity toStageEntity = commonJumpDTO.getToStageEntity();
        String nextStageCode = "";
        Long nextStageId = 0L;
        Long nextStageProcessId = 0L;
        if (Objects.nonNull(toStageEntity)) {
            nextStageCode = toStageEntity.getCode();
            nextStageId = toStageEntity.getId();
            nextStageProcessId = toStageEntity.getStageProcessId();
        }

        Integer businessType = XbbRefTypeEnum.PAAS.getCode();
        Integer saasMark = SaasMarkEnum.PAAS.getCode();
        PaasFormEntity paasForm = paasFormModel.getByKey(formId, corpid);
        if (Objects.nonNull(paasForm) && Objects.equals(paasForm.getSaasMark(), SaasMarkEnum.SAAS.getCode())) {
            businessType = paasForm.getBusinessType();
            saasMark = paasForm.getSaasMark();
        }
        if (commonHelp.isOpenWorkFlow(corpid)) {
            // 工作流
            List<WorkflowEntity> workflowEntities = workflowFormDataOperationService.getSatisfyTriggerEntitys(corpid, formId, Objects.equals(saasMark, SaasMarkEnum.SAAS.getCode()) ? businessType : null, Arrays.asList(TriggerEventTypeEnum.ONLY_UPDATE.getType(), TriggerEventTypeEnum.ADD_OR_UPDATE.getType()));
            for (WorkflowEntity workflowEntity : workflowEntities) {
                WorkflowNodeEntity startNode = workflowNodeModel.getByUId(workflowEntity.getId(), corpid, "startNode");
                FormTriggerNode formTriggerNode = JSON.parseObject(startNode.getConfigData(), FormTriggerNode.class);
                if (CollectionsUtil.isEmpty(formTriggerNode.getNeedApproveFields()) || formTriggerNode.getNeedApproveFields().contains(stageAttr)) {
                    //是否启用新工作流
                    PaasFormExplainEntity explain = paasFormExplainModel.getByFormId(formId, corpid);
                    Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(explain.getExplains(), null);
                    BusinessRuleInfoPojo businessRuleInfoPojo = new BusinessRuleInfoPojo(startNode.getCorpid(), startNode.getFormId(), startNode.getBusinessType(), startNode.getSaasMark(), explainMap);
                    PaasFormDataEntityExt paasFormDataEntityExtClone = (PaasFormDataEntityExt) CloneUtil.deepClone(paasFormDataEntityExt);
                    if (Objects.nonNull(toStageEntity)) {
                        // 详情页阶段跳转，用跳转之后的阶段去匹配触发条件-----59089 【KA大客户】【B级】阶段审批异常
                        paasFormDataEntityExtClone.getData().put(stageAttr, toStageEntity.getCode());
                    }
                    boolean flag = workflowFormDataOperationService.validatePreCondition(formTriggerNode.getTriggerConditions(), paasFormDataEntityExtClone, businessRuleInfoPojo);
                    if(!flag){
                        break;
                    }
                    workflowRequired(paasFormDataEntityExt, startNode, commonJumpDTO, WorkflowExecutionTypeEnum.FORM, stageAttr, null);

                    if (Objects.equals(1, workflowEntity.getIsApprove())) {
                        noApprovalRequired = 3;
                    } else {
                        // 无审批节点
                        noApprovalRequired = 4;
                    }
                    break;
                }
            }
        } else {
            // 老审批
            Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            params.put("del", 0);
            params.put("corpid", corpid);
            params.put("formId", formId);
            params.put("enable", 1);
            List<PaasProcessTemplateEntityExt> paasProcessTemplateEntityExtList = paasProcessTemplateModel.list(params);
            if (paasProcessTemplateEntityExtList.size() > 0 && paasProcessTemplateEntityExtList.get(0).getNeedApproveFieldList().contains(stageAttr)) {
                JSONObject newData = (JSONObject) CloneUtil.deepClone(paasFormDataEntityExt.getData());
                if (Objects.equals(XbbRefTypeEnum.CONTRACT.getCode(), businessType)) {
                    newData.remove(ContractEnum.PRODUCT.getAttr());
                }
                newData.put(stageAttr, nextStageCode);
                newData.put(PaasStageEnum.STAGE_PROCESS_ID.getAttr(), nextStageProcessId);
                newData.put(PaasStageEnum.STAGE_ID.getAttr(), nextStageId);

                // 计算阶段比例
                StageJumpHandle stageJumpHandle = stageJumpMap.get(toStageEntity.getType());
                Integer proportion = stageJumpHandle.getJumpIntoProportion(paasFormDataEntityExt.getId(), corpid, formId, toStageEntity.getId(), saasMark, businessType, toStageEntity.getOutProportion());
                newData.put(PaasStageEnum.STAGE_RATIO.getAttr(), proportion);

                if (Objects.equals(businessType, XbbRefTypeEnum.CONTRACT.getCode())) {
                    Map<Integer, List<UserTeamEntity>> userMap = userTeamService.getUserTeam(paasFormDataEntityExt.getId(), corpid, businessType);
                    // 负责人
                    if (userMap.containsKey(1)) {
                        List<UserTeamEntity> mainUserList = userMap.get(1);
                        List<String> mainIdList = new ArrayList<>();
                        for (UserTeamEntity userTeamEntity : mainUserList) {
                            mainIdList.add(userTeamEntity.getUserId());
                        }
                        newData.put(ContractEnum.OWNER_ID.getAttr(), mainIdList);
                    }
                    if (userMap.containsKey(0)) {
                        List<UserTeamEntity> coUserList = userMap.get(0);
                        List<String> coIdList = new ArrayList<>();
                        for (UserTeamEntity userTeamEntity : coUserList) {
                            coIdList.add(userTeamEntity.getUserId());
                        }
                        newData.put(ContractEnum.MINOR_USER.getAttr(), coIdList);
                    }
                    List<ContractProductEntity> productList = contractProductModel.getProductsByConId(paasFormDataEntityExt.getId(), corpid);
                    stageLogHelp.formatProductForProcess(productList, newData);
                }

                StartProcessDTO startProcessDTO = new StartProcessDTO();
                BeanUtil.copyProperties(commonJumpDTO, startProcessDTO);
                BeanUtil.copyProperties(paasFormDataEntityExt, startProcessDTO);
                List<PaasUserEntity> list = paasUserModel.getPaasUserList( corpid, paasFormDataEntityExt.getId(), null);
                // 负责人
                if (CollectionsUtil.isNotEmpty(list)) {
                    List<String> mainIdList = new ArrayList<>();
                    for (PaasUserEntity userTeamEntity : list) {
                        mainIdList.add(userTeamEntity.getUserId());
                    }
                    newData.put(FieldTypeEnum.OWNERID.getAlias(), mainIdList);
                }
                startProcessDTO.setData(newData);
                startProcessDTO.setFormDataId(paasFormDataEntityExt.getId());
                startProcessDTO.setCreatorId(commonJumpDTO.getUserId());
                startProcessDTO.setSaasMark(saasMark);
                startProcessDTO.setBusinessType(businessType);
                StartProcessVO startProcessVO = processStartHelp.startProcess(startProcessDTO, paasFormDataEntityExt);
                noApprovalRequired = startProcessVO.getNoApprovalRequired();
            }
        }
        return noApprovalRequired;
    }

    @Override
    public void workflowRequired(PaasFormDataEntityExt paasFormDataEntityExt, WorkflowNodeEntity startNode, CommonJumpDTO commonJumpDTO, WorkflowExecutionTypeEnum workflowExecutionTypeEnum, String stageAttr, WorkflowExecutionEntity workflowExecutionEntity) throws XbbException {
        String corpid = commonJumpDTO.getCorpid();
        Long formId = commonJumpDTO.getFormId();
        PaasStageEntity toStageEntity = commonJumpDTO.getToStageEntity();
        String nextStageCode = "";
        Long nextStageId = 0L;
        Long nextStageProcessId = 0L;
        Integer proportion = 0;
        Integer businessType = XbbRefTypeEnum.PAAS.getCode();
        Integer saasMark = SaasMarkEnum.PAAS.getCode();
        Integer subBusinessType = null;
        PaasFormEntity paasForm = paasFormModel.getByKey(formId, corpid);
        if (Objects.nonNull(paasForm) && Objects.equals(paasForm.getSaasMark(), SaasMarkEnum.SAAS.getCode())) {
            businessType = paasForm.getBusinessType();
            saasMark = paasForm.getSaasMark();
            subBusinessType = businessType;
        }
        if (Objects.nonNull(toStageEntity)) {
            nextStageCode = toStageEntity.getCode();
            nextStageId = toStageEntity.getId();
            nextStageProcessId = toStageEntity.getStageProcessId();
            // 计算阶段比例
            StageJumpHandle stageJumpHandle = stageJumpMap.get(toStageEntity.getType());
            proportion = stageJumpHandle.getJumpIntoProportion(paasFormDataEntityExt.getId(), corpid, formId, toStageEntity.getId(), saasMark, businessType, toStageEntity.getOutProportion());
        }

        // backup
        JSONObject oldDataObj = (JSONObject) CloneUtil.deepClone(paasFormDataEntityExt.getData());
        FormDataUtil.setSystemData(oldDataObj, paasFormDataEntityExt);
        long now = DateTimeUtil.getInt();
        List<PaasUserEntity> paasUserList = paasUserModel.getPaasUserList(corpid, paasFormDataEntityExt.getId(), null);
        oldDataObj.put(StringConstant.USER_TEAM, paasUserList);

        if (Objects.equals(businessType, XbbRefTypeEnum.CONTRACT.getCode())) {
            List<ContractUserEntity> contractUserList = contractUserModel.getContractUserList(corpid, paasFormDataEntityExt.getId(), null);
            oldDataObj.put(StringConstant.USER_TEAM, contractUserList);
            List<ContractProductEntity> productList = contractProductModel.getProductsByConId(paasFormDataEntityExt.getId(), corpid);
            oldDataObj.put(StringConstant.PRODUCT, productList);
        }
        WorkflowBackupDataEntity workflowBackupDataEntity = new WorkflowBackupDataEntity(corpid, paasFormDataEntityExt.getAppId(),
                paasFormDataEntityExt.getFormId(), paasFormDataEntityExt.getMenuId(), 0L, 0L, paasFormDataEntityExt.getId(), oldDataObj, now, now, DelEnum.NORMAL.getDel());
        workflowBackupDataModel.insert(workflowBackupDataEntity);
        //构建mq消息
        FormDataUtil.setSystemData(paasFormDataEntityExt.getData(), paasFormDataEntityExt);
        Data oldData = new Data(startNode.getAppId(), startNode.getMenuId(), startNode.getFormId(), paasFormDataEntityExt.getId(), oldDataObj, startNode.getBusinessType(), startNode.getSaasMark(), startNode.getId(), subBusinessType);
        if (Objects.equals(businessType, XbbRefTypeEnum.CONTRACT.getCode())) {
            List<ContractProductEntity> productEntities = contractProductModel.getProductsByConId(paasFormDataEntityExt.getId(), corpid);
            stageLogHelp.formatProductForProcess(productEntities, paasFormDataEntityExt.getData());
        }
        // 将需要更新的字段，更新到主数据
        JSONObject updateDataJson = new JSONObject();
        updateDataJson.put(stageAttr, nextStageCode);
        updateDataJson.put(PaasStageEnum.STAGE_PROCESS_ID.getAttr(), nextStageProcessId);
        updateDataJson.put(PaasStageEnum.STAGE_ID.getAttr(), nextStageId);
        updateDataJson.put(PaasStageEnum.STAGE_RATIO.getAttr(), proportion);
        // 更新数据
        UpdateDataEntity updateData = ExplainUtil.getUpdateData(paasFormDataEntityExt.getId(), updateDataJson, corpid);
        proUpdateHelp.updateBatch(saasMark, businessType, corpid, Collections.singletonList(updateData), true, WriteRequest.RefreshPolicy.NONE);

        paasFormDataEntityExt.getData().putAll(updateDataJson);
        WorkflowTransferPOJO workflowTransferPOJO = WorkflowTransferHelp.createTransferData(paasFormDataEntityExt, null, null, null, corpid, commonJumpDTO.getLoginUser(), startNode, WorkflowOperateEnum.UPDATE.getType(), 0, subBusinessType);
        workflowTransferPOJO.setBackupDataId(workflowBackupDataEntity.getId());
        workflowTransferPOJO.setOldData(oldData);

        workflowTransferPOJO.setExecutionType(workflowExecutionTypeEnum.getCode());
        workflowTransferPOJO.setIsFromStage(true);
        workflowTransferPOJO.setToStageId(nextStageId);
        if (Objects.isNull(commonJumpDTO.getFromStageEntity())) {
            workflowTransferPOJO.setFromStageId(null);
        } else {
            workflowTransferPOJO.setFromStageId(commonJumpDTO.getFromStageEntity().getId());
        }
        if (!Objects.isNull(workflowExecutionEntity)) {
            workflowTransferPOJO.setParentExecutionId(workflowExecutionEntity.getId());
            workflowTransferPOJO.setLinkKey(workflowExecutionEntity.getLinkKey());
        }
        workflowTransferPOJO.setStageProcessId(commonJumpDTO.getStageProcessEntity().getId());

        JSONObject newDataObj = new JSONObject();
        newDataObj.putAll(oldDataObj);
        newDataObj.putAll(updateDataJson);
        Data newData = new Data(startNode.getAppId(), startNode.getMenuId(), startNode.getFormId(), paasFormDataEntityExt.getId(),
                newDataObj, startNode.getBusinessType(), startNode.getSaasMark(), startNode.getId(), Objects.equals(saasMark, SaasMarkEnum.PAAS.getCode()) ? XbbRefTypeEnum.SYSTEM.getCode() : subBusinessType);
        workflowTransferPOJO.setData(newData);

        WorkflowRabbitmqDTO workflowRabbitmqDTO = new WorkflowRabbitmqDTO(workflowTransferPOJO, startNode, null);
        workflowProducer.startWorkflow(workflowRabbitmqDTO);
    }

    @Override
    public void jumpSpecialDeal(StageJumpSpecialDealDTO stageJumpSpecialDealDTO) throws XbbException {

    }
}
